home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Mac Game Programming Gurus / TricksOfTheMacGameProgrammingGurus.iso / More Source / C⁄C++ / graph3D / graph3D source / graph3D.c < prev    next >
C/C++ Source or Header  |  1993-09-17  |  37KB  |  2,089 lines

  1. /*
  2.     Copyright '89    Christopher Moll
  3.     all rights reserved
  4. */
  5.  
  6.  
  7. #include    "graph3D.h"
  8.  
  9. #ifdef    _LSC3_
  10. #    include <ColorToolbox.h>
  11. #    include <MemoryMgr.h>
  12. #    include <FileMgr.h>
  13. #    include <WindowMgr.h>
  14. #    include <DialogMgr.h>
  15. #    include <EventMgr.h>
  16. #    include <TextEdit.h>
  17. #    include <DeskMgr.h>
  18. #    include <MenuMgr.h>
  19. #    include <ScrapMgr.h>
  20. #endif
  21.  
  22.  
  23. extern    Real    startR, startT;
  24. extern    Real    endR, endT;
  25. extern    Real    deltaR, deltaT;
  26. extern    int        numR, numT;
  27.  
  28. extern    Real    startX, startY;
  29. extern    Real    endX, endY;
  30. extern    Real    deltaX, deltaY;
  31. extern    int        numX, numY;
  32.  
  33. extern    WindowRecord    gwindRecord;
  34.  
  35. extern    Uchar        *gridFace;
  36.  
  37.  
  38.  
  39. /* windows */
  40. GrafPtr            windManPort;
  41.  
  42. WindowPtr        graphWind;
  43.  
  44.  
  45. /* Dialogs */
  46. DialogRecord    sdialRecord;    /* storage for the dialog */
  47. DialogPtr        specDial;
  48. Boolean            specDOpen = FALSE;
  49. DialogRecord    lmdialRecord;    /* storage for the dialog */
  50. DialogPtr        limtDial;
  51. Boolean            limtDOpen = FALSE;
  52. DialogRecord    funcDialRecord;    /* storage for the dialog */
  53. DialogPtr        functDial;
  54. Boolean            functDOpen = FALSE;
  55.  
  56.  
  57. /* menus */
  58. MenuHandle        appleMenu, fileMenu, editMenu, plotMenu,
  59.                 gTypeMenu, windwMenu;
  60.  
  61.  
  62. /* Clipboard stuff */
  63. int            scrapCompare;    /* status of the deskscrap (clipboard) */
  64. Boolean        scrapDirty;        /* deskscrap has been changed */
  65. Boolean        isScrapTE;        /* there's text in the deskscrap */
  66. Boolean        isScrapPIC;        /* there's a picture in the deskscrap */
  67.  
  68. Boolean        appActive = TRUE;
  69.  
  70.  
  71. Boolean        useMainFunc;
  72.  
  73. int        mainFunct[64];
  74. int        numMnOps;
  75. Real    mnConsts[30];
  76. int        numMnConsts = 0;
  77.  
  78. int        derivFunct[64];
  79. int        numDerivOps;
  80. Real    derivConsts[30];
  81. int        numDerivConsts = 0;
  82.  
  83.  
  84. /* graph points in various forms */
  85. Real        *funcResults = NIL;        /* changes when function changed,
  86.                                         new file opened, etc. */
  87. Vector        *scalVectResults = NIL;        /* changes when function changed,
  88.                                         new file opened, etc. */
  89. Point        *graphPoints = NIL;        /* changes when rotation changes */
  90.  
  91. Vector        maxVect, minVect;
  92.  
  93. Point    XaxisPt, YaxisPt, ZaxisPt;
  94. Point    Origin = {0, 0};
  95. Rect    graphRect = {40, 40, 300, 470};
  96.  
  97.  
  98.  
  99. Real    rotMatrx[3][3];
  100.  
  101. Real    scale;
  102.  
  103.  
  104. Boolean        functCurrent = FALSE;    /* function evaluated and stored in funcResults*/
  105. Boolean        specsCurrent = FALSE;    /* funtion evaluated according to current specification
  106.                                         dialog contents ('begin', 'end').
  107.                                                     If not , reevaluate function */
  108. Boolean        vectrsCurrent = FALSE;    /* vectors have been set from the function */
  109. Boolean        pntsCurrent = FALSE;    /* pnts have been taken from the vectors and scaled
  110.                                         to fit in window */
  111.  
  112. Boolean        noRedrawGrph = FALSE;    /* graph being worked on;
  113.                                     don't try to redraw it */
  114.  
  115. Boolean        hideSurface = FALSE, useHeight = FALSE;
  116. Boolean        xAxPos, yAxPos;
  117. int            graphType = FUNCT_GTYPE;
  118.  
  119. Boolean        drawToScreen = FALSE;
  120.  
  121.  
  122. Real    zScale = 1.0;
  123. Real    ceilgZ = 1e100, floorZ = -1e100;
  124.  
  125. Real    cosSrc = .86602540378444, sinSrc = .5;    /* 30 degrees */
  126.  
  127.  
  128. Boolean        colorQD, scrnColor, colorNorms;
  129. Boolean        grphOnScrn = FALSE;
  130.  
  131. PatternList        *greyList;
  132.  
  133.  
  134. EventRecord        theEvent;
  135. Boolean            inMultiFndr;
  136. long            sleepPeriod = 2;
  137.  
  138. long        startRedraw = -1;
  139.  
  140. long    MoveToAddr, LineToAddr, FixMulAddr;
  141.  
  142.  
  143. void    ReDrwLine(...);
  144.  
  145.  
  146. main()
  147. {
  148.     DoSetup();
  149.     SelectWindow(graphWind);
  150.  
  151.     while (1)
  152.     {
  153.         DialogIdle();
  154.         if (inMultiFndr)
  155.         {
  156.             if (WaitNextEvent(everyEvent, &theEvent, sleepPeriod, NIL))
  157.             {
  158.                 DoEvent();
  159.                 InitCursor();
  160.             }
  161.         }
  162.         else
  163.         {
  164.             if (GetNextEvent(everyEvent, &theEvent))
  165.             {
  166.                 DoEvent();
  167.                 InitCursor();
  168.             }
  169.             SystemTask();
  170.         }
  171.     }
  172. }
  173.  
  174. static
  175. DialogIdle()
  176. {
  177.     WindowPtr    frontW;
  178.  
  179.     frontW = FrontWindow();
  180.  
  181.     if (frontW EQ functDial)
  182.         TEIdle(funcDialRecord.textH);
  183.     else if (frontW EQ specDial)
  184.         TEIdle(sdialRecord.textH);
  185.     else if (frontW EQ limtDial)
  186.         TEIdle(lmdialRecord.textH);
  187. }
  188.  
  189. DoEvent()
  190. {
  191.     DialogPtr    theDial;
  192.     int            theItem;
  193.     Boolean        result, ScrnHasColor();
  194.  
  195.     scrnColor = ScrnHasColor();    /* check current screen status */
  196.  
  197.     if (theEvent.what EQ resumEvt)
  198.         DoSuspndRsm(theEvent.message);
  199.     
  200.     if (IsDialogEvent(&theEvent))
  201.         DoDialogEvent();
  202.     else
  203.     {
  204.         switch (theEvent.what) {
  205.         case nullEvent:
  206.             break;
  207.         case mouseDown:
  208.             DoMouseDown();
  209.             break;
  210.         case mouseUp:
  211.             break;
  212.         case keyDown:
  213.         case autoKey:
  214.             DoKeyDown();
  215.             break;
  216.         case updateEvt:
  217.             DoUpdate();
  218.             break;
  219.         case diskEvt:
  220.             break;
  221.         case activateEvt:
  222.             DoActivate();
  223.             break;
  224.         case networkEvt:
  225.         case driverEvt:
  226.             break;
  227.         }
  228.     }
  229. }
  230.  
  231. static
  232. DoDialogEvent()
  233. {
  234.     DialogPtr    theDial;
  235.     int            theItem;
  236.     Boolean        ChkCmndKey(), ChkNmbrKey();
  237.  
  238.     theDial = FrontWindow();
  239.  
  240.     if ((theEvent.what EQ keyDown) OR (theEvent.what EQ autoKey))
  241.     {
  242.         if (ChkCmndKey(theDial))
  243.             return;
  244.         if ((theDial EQ specDial) OR (theDial EQ limtDial))
  245.         {
  246.             if (NOT(ChkNmbrKey()))
  247.                 return;
  248.         }
  249.         else
  250.             functCurrent = FALSE;
  251.     }
  252.  
  253.     if (theEvent.what EQ activateEvt)    /* if it's a DA, get or write clip */
  254.     {
  255.         if (theEvent.modifiers & activeFlag)
  256.             ReadDeskScrap();
  257.         else
  258.             WriteDeskScrap();
  259.     }
  260.  
  261.     DialogSelect(&theEvent, &theDial, &theItem);
  262.     if (theItem EQ DIALI_S_REDRWB)
  263.         DoRedraw();
  264. }
  265.  
  266. /*** Force an update of the graph ***/
  267. InvalidGraph()
  268. {
  269.     GrafPtr    savePort;
  270.  
  271.     GetPort(&savePort);
  272.     SetPort(graphWind);
  273.         InvalRect(&graphWind->portRect);
  274.     SetPort(savePort);
  275. }
  276.  
  277. /*** Called when a modeless dialog is frontmost; checks for and
  278.         deals with command keys ***/
  279. static
  280. Boolean
  281. ChkCmndKey(theDial)
  282. DialogPtr    theDial;
  283. {
  284.     if (theEvent.modifiers & cmdKey)
  285.     {
  286.         DoKeyDown();
  287.         return(TRUE);
  288.     }
  289.  
  290.     return(FALSE);
  291. }
  292.  
  293. static
  294. Boolean
  295. ChkNmbrKey()
  296. {
  297.     char    typed;
  298.  
  299.     typed = (char)(theEvent.message & charCodeMask);
  300.  
  301.     if (IS_DIGIT(typed))
  302.         return(TRUE);
  303.  
  304.     switch (typed)
  305.     {
  306.     case '-':
  307.     case '.':
  308.     case 'e':
  309.     case '\t':
  310.     case '\b':
  311.         return(TRUE);
  312.     }
  313.  
  314.     return(FALSE);
  315. }
  316.  
  317. static
  318. DoMouseDown()
  319. {
  320.     int thePart;
  321.     WindowPtr whichWindow;
  322.  
  323.     thePart = FindWindow( theEvent.where, &whichWindow);
  324.  
  325.     switch (thePart) {
  326.     case inDesk:
  327.         break;
  328.     case inMenuBar:
  329.         DoMenuClick();
  330.         break;
  331.     case inSysWindow:
  332.         SystemClick(&theEvent, whichWindow);
  333.         break;
  334.     case inContent:
  335.         DoContent(whichWindow);
  336.         break;
  337.     case inDrag:
  338.         DoDrag(whichWindow);
  339.         break;
  340.     case inGrow:
  341.         DoGrow(whichWindow);
  342.         break;
  343.     case inGoAway:
  344.         DoGoAway(whichWindow, TRUE);
  345.         break;
  346.     case inZoomIn:
  347.     case inZoomOut:
  348.         DoZoom(whichWindow, thePart);
  349.         break;
  350.     }
  351. }
  352.  
  353. static
  354. DoMenuClick()
  355. {
  356.     long menuChoice;
  357.  
  358.     menuChoice = MenuSelect(theEvent.where);
  359.     DoMenuChoice(menuChoice);
  360. }
  361.  
  362. static
  363. DoMenuChoice(menuChoice)
  364. long menuChoice;
  365. {
  366.     Clock();
  367.     switch(HiWord(menuChoice)) {
  368.     case MENU_APPLE:
  369.         DoAppleChoice( LoWord(menuChoice) );
  370.         break;
  371.     case MENU_FILE:
  372.         DoFileMenu(LoWord(menuChoice));
  373.         break;
  374.     case MENU_EDIT:
  375.         DoEditMenu(LoWord(menuChoice));
  376.         break;
  377.     case MENU_PLOT:
  378.         DoPlotMenu(LoWord(menuChoice));
  379.         break;
  380.     case MENU_GTYP:
  381.         DoGTypeMenu(LoWord(menuChoice));
  382.         break;
  383.     case MENU_WIND:
  384.         DoWindwMenu(LoWord(menuChoice));
  385.         break;
  386.     }
  387.  
  388.     HiliteMenu(0); /* unhilight the selected menu */
  389. }
  390.  
  391. static
  392. DoAppleChoice(theItem)
  393. int theItem;
  394. {
  395.     char    accName[256];
  396.     int        accNum, i;
  397.  
  398.     WriteDeskScrap();
  399.  
  400.     if (theItem EQ 1)
  401.         DoAbout();
  402.     else
  403.     {
  404.         GetItem(appleMenu, theItem, accName);
  405.         accNum = OpenDeskAcc(accName);
  406.     }
  407. }
  408.  
  409. static
  410. DoAbout()
  411. {
  412.     InitCursor();
  413.     Alert(ALRT_ABOUT, NIL);
  414. }
  415.  
  416. static
  417. DoFileMenu(theItem)
  418. int theItem;
  419. {
  420.     Boolean        ReadData();
  421.  
  422.     switch(theItem) {
  423.     case FILE_OPEN:
  424.         if (graphType NEQ FDATA_GTYPE)
  425.             DoGTypeMenu(FDATA_GTYPE);    /* "Data File" from gtype menu */
  426.         else
  427.         {
  428.             if (ReadData())
  429.                 InvalidGraph();
  430.         }
  431.         break;
  432.     case FILE_OPEN_MAND:
  433.         OpenMandel();
  434.         break;
  435.     case FILE_CLOSE:
  436.         DoGoAway(FrontWindow(), FALSE);
  437.         break;
  438.     case FILE_SVBITM:
  439.         SavePICT(FALSE);
  440.         break;
  441.     case FILE_SVOBJ:
  442.         SavePICT(TRUE);
  443.         break;
  444.     case FILE_QUIT:
  445.         DoQuit();
  446.         break;
  447.     }
  448. }
  449.  
  450. static
  451. DoQuit()
  452. {
  453.     CloseWindow(graphWind);
  454.     if (scrnColor)
  455.         GetNewCWindow(130, &gwindRecord, (WindowPtr)-1L);
  456.     exit();
  457. }
  458.  
  459. static
  460. DoEditMenu(theItem)
  461. int theItem;
  462. {
  463.     WindowPtr    frontW;
  464.     frontW = FrontWindow();
  465.  
  466.     switch(theItem) {
  467.     case 1: /* Undo */
  468.         SystemEdit(undoCmd);
  469.         break;
  470.     case 3: /* Cut */
  471.         if (NOT(SystemEdit(cutCmd)))
  472.             DoCut(frontW);
  473.         break;
  474.     case 4: /* Copy */
  475.         if (NOT(SystemEdit(copyCmd)))
  476.             DoCopy(frontW);
  477.         break;
  478.     case 5: /* Paste */
  479.         if (NOT(SystemEdit(pasteCmd)))
  480.             DoPaste(frontW);
  481.         break;
  482.     case 6: /* Clear */
  483.         if (NOT(SystemEdit(clearCmd)))
  484.             DoClear(frontW);
  485.         break;
  486.     }
  487. }
  488.  
  489. static
  490. DoCut(frontW)
  491. WindowPtr    frontW;
  492. {
  493.     Boolean        IsDialog();
  494.     
  495.     if (IsDialog(frontW))
  496.     {
  497.         DlgCut(frontW);
  498.         scrapDirty = TRUE;
  499.     }
  500. }
  501.  
  502. static
  503. DoCopy(frontW)
  504. WindowPtr    frontW;
  505. {
  506.     Boolean        IsDialog();
  507.     
  508.     if (IsDialog(frontW))
  509.         DlgCopy(frontW);
  510.     else if (frontW EQ graphWind)
  511.         CopyGraph();
  512.     scrapDirty = TRUE;
  513. }
  514.  
  515. static
  516. CopyGraph()
  517. {
  518.     PicHandle    GetGraphPICT();
  519.     PicHandle    graphPict;
  520.  
  521.     graphPict = GetGraphPICT(OptionDown());
  522.     if (NOT(graphPict))
  523.         return;
  524.  
  525.     ZeroScrap();
  526.     PutScrap(GetHandleSize(graphPict), 'PICT', *graphPict);
  527.     isScrapPIC = TRUE;
  528.     isScrapTE = FALSE;
  529. }
  530.  
  531. static
  532. DoPaste(frontW)
  533. WindowPtr    frontW;
  534. {
  535.     Boolean        IsDialog();
  536.     
  537.     if (IsDialog(frontW))
  538.         DlgPaste(frontW);
  539. }
  540.  
  541. static
  542. DoClear(frontW)
  543. WindowPtr    frontW;
  544. {
  545.     Boolean        IsDialog();
  546.     
  547.     if (IsDialog(frontW))
  548.         DlgDelete(frontW);
  549. }
  550.  
  551. static
  552. Boolean
  553. IsDialog(theWind)
  554. WindowPtr    theWind;
  555. {
  556.     return
  557.             ((theWind EQ specDial) OR 
  558.             (theWind EQ limtDial) OR 
  559.             (theWind EQ functDial));
  560. }
  561.  
  562. static
  563. DoPlotMenu(theItem)
  564. int theItem;
  565. {
  566.     switch(theItem) {
  567.     case PLOT_WIREFRAM: /* just lines */
  568.         hideSurface = FALSE;
  569.         useHeight = FALSE;
  570.         CheckItem(plotMenu, PLOT_WIREFRAM, TRUE);
  571.         CheckItem(plotMenu, PLOT_SHDSURF, FALSE);
  572.         CheckItem(plotMenu, PLOT_SHDHITE, FALSE);
  573.         InvalidGraph();
  574.         break;
  575.     case PLOT_SHDSURF: /* Hide surfaces */
  576.         CheckItem(plotMenu, PLOT_WIREFRAM, FALSE);
  577.         if (useHeight)    /* hideSurface TRUE */
  578.         {
  579.             useHeight = FALSE;
  580.             pntsCurrent = FALSE;
  581.             CheckItem(plotMenu, PLOT_SHDSURF, TRUE);
  582.             CheckItem(plotMenu, PLOT_SHDHITE, FALSE);
  583.             CheckHideView();
  584.             InvalidGraph();
  585.         }
  586.         else if (NOT(hideSurface))
  587.         {
  588.             hideSurface = TRUE;
  589.             useHeight = FALSE;
  590.             pntsCurrent = FALSE;
  591.             CheckItem(plotMenu, PLOT_SHDSURF, TRUE);
  592.             CheckHideView();
  593.             InvalidGraph();
  594.         }
  595.         break;
  596.     case PLOT_SHDHITE: /* Shade by hight */
  597.         CheckItem(plotMenu, PLOT_WIREFRAM, FALSE);
  598.         if (NOT(useHeight))
  599.         {
  600.             hideSurface = TRUE;
  601.             useHeight = TRUE;
  602.             pntsCurrent = FALSE;
  603.             CheckItem(plotMenu, PLOT_SHDSURF, FALSE);
  604.             CheckItem(plotMenu, PLOT_SHDHITE, TRUE);
  605.             CheckHideView();
  606.             InvalidGraph();
  607.         }
  608.         break;
  609.     case PLOT_DRWSCRN: /* Draw to screen or not */
  610.         ToggleDrwScreen();
  611.         break;
  612.     case PLOT_SETLITE: /* Set light source */
  613.         SetLightSrc();
  614.         break;
  615.     case PLOT_ZEROROT: /* Zero Rotation */
  616.         MkIDMat(rotMatrx);
  617.         vectrsCurrent = FALSE;
  618.         InvalidGraph();
  619.         break;
  620.     case PLOT_NORMVIEW: /* Normal View */
  621.         MkRotMat(0.0, -.3, -.3, rotMatrx);
  622.         vectrsCurrent = FALSE;
  623.         InvalidGraph();
  624.         break;
  625.     case PLOT_TOPVIEW: /* Top View */
  626.         MkRotMat(0.0, PI/2.0, 0.0, rotMatrx);
  627.         vectrsCurrent = FALSE;
  628.         InvalidGraph();
  629.         break;
  630.     case PLOT_REDRAW: /* ReDraw */
  631.         DoRedraw();
  632.         break;
  633.     }
  634.     SetPlotMenu();
  635. }
  636.  
  637. CheckHideView()
  638. {
  639.     Vector        testVect, resVect;
  640.  
  641.     testVect.x = 1;
  642.     testVect.y = 0;
  643.     testVect.z = 0;
  644.     MatrxMul(rotMatrx, &testVect, &resVect);
  645.  
  646.     xAxPos = (resVect.x > 0);
  647.     testVect.x = 0;
  648.     testVect.y = 1;
  649.     MatrxMul(rotMatrx, &testVect, &resVect);
  650.     yAxPos = (resVect.x > 0);
  651. }
  652.  
  653. ToggleDrwScreen()
  654. {
  655.     drawToScreen = NOT(drawToScreen);
  656.     CheckItem(plotMenu, PLOT_DRWSCRN, drawToScreen);
  657.     InvalidGraph();
  658. }
  659.  
  660. static
  661. SetLightSrc()
  662. {
  663.     Point    center, chosen;
  664.     EventRecord    msEvent;
  665.     Real    horiz, vert, len;
  666.  
  667.     InitCursor();
  668.     SelectWindow(graphWind);
  669.     center.h = (graphWind->portRect.right - graphWind->portRect.left) >> 1;
  670.     center.v = (graphWind->portRect.bottom - graphWind->portRect.top) >> 1;
  671.  
  672.     while (!GetNextEvent(mDownMask, &msEvent));
  673.     chosen = msEvent.where;
  674.     GlobalToLocal(&chosen);
  675.  
  676.     horiz = chosen.h - ((graphWind->portRect.right - graphWind->portRect.left) >> 1);
  677.     vert = chosen.v - ((graphWind->portRect.bottom - graphWind->portRect.top) >> 1);
  678.     len = SQ(horiz) + SQ(vert);
  679.     len = -sqrt(len);
  680.     sinSrc = horiz / len;
  681.     cosSrc = vert / len;
  682.  
  683.     if (hideSurface AND NOT(useHeight))
  684.         InvalidGraph();
  685.     pntsCurrent = FALSE;
  686. }
  687.  
  688. static
  689. DoRedraw()
  690. {
  691.     GetLimtDCont();
  692.  
  693.     startRedraw = Ticks;
  694.  
  695.     if (graphType NEQ FDATA_GTYPE)
  696.     {
  697.         GetSpecDCont();
  698.         if (NOT(specsCurrent AND functCurrent))
  699.             if ((graphType EQ FUNCT_GTYPE) OR (graphType EQ DERIV_GTYPE))
  700.                 EvalFunction();
  701.             else
  702.                 EvalCylindFunct();
  703.     }
  704.     
  705.     InvalidGraph();
  706. }
  707.  
  708. DoGTypeMenu(theItem)
  709. int theItem;
  710. {
  711. Rect    fWindRect;
  712.  
  713.     switch(theItem) {
  714.     case FUNCT_GTYPE: /* Function */
  715.         SetToFunction();
  716.         break;
  717.     case CYLIND_GTYPE: /* Cylindrical */
  718.         SetToCylind();
  719.         break;
  720.     case DERIV_GTYPE: /* Derivative */
  721.         SetToDeriv();
  722.         break;
  723.     case FDATA_GTYPE: /* File Data */
  724.         SetToDataFile();
  725.         break;
  726.     }
  727. }
  728.  
  729. static
  730. SetToFunction()
  731. {
  732.     if (graphType NEQ FUNCT_GTYPE)
  733.     {
  734.         CheckItem(gTypeMenu, graphType, FALSE);
  735.         SetFunctDialType(FUNCT_GTYPE);
  736.         CheckItem(gTypeMenu, graphType, TRUE);
  737.     }
  738. }
  739.  
  740. static
  741. SetToCylind()
  742. {
  743.     if (graphType NEQ CYLIND_GTYPE)
  744.     {
  745.         CheckItem(gTypeMenu, graphType, FALSE);
  746.         SetFunctDialType(CYLIND_GTYPE);
  747.         CheckItem(gTypeMenu, graphType, TRUE);
  748.     }
  749. }
  750.  
  751. static
  752. SetToDeriv()
  753. {
  754.     if (graphType NEQ DERIV_GTYPE)
  755.     {
  756.         CheckItem(gTypeMenu, graphType, FALSE);
  757.         SetFunctDialType(DERIV_GTYPE);
  758.         CheckItem(gTypeMenu, graphType, TRUE);
  759.     }
  760. }
  761.  
  762. ARD(a)
  763. register int a;
  764. {
  765.     DeBug();
  766. }
  767.  
  768. static
  769. SetToDataFile()
  770. {
  771.     Boolean        ReadData();
  772.  
  773.     if (graphType NEQ FDATA_GTYPE)
  774.         if (ReadData())
  775.         {
  776.             CheckItem(gTypeMenu, graphType, FALSE);
  777.             SetFunctDialType(FDATA_GTYPE);
  778.             CheckItem(gTypeMenu, graphType, TRUE);
  779.             InvalidGraph();
  780.         }
  781. }
  782.  
  783. static
  784. SetFunctDialType(newType)
  785. int    newType;
  786. {
  787.     int    oldType;
  788.     
  789.     oldType = graphType;
  790.     graphType = newType;
  791.  
  792.     CloseSpecDial();
  793.     ShowSpecs();
  794.  
  795.     if (newType EQ FDATA_GTYPE)
  796.     {
  797.         if ((oldType EQ FUNCT_GTYPE) OR (oldType EQ DERIV_GTYPE))
  798.             CloseFunctDial();
  799.     }
  800.     else
  801.     {
  802.         CloseFunctDial();
  803.         ShowFunctDial();
  804.     }
  805. }
  806.  
  807. static
  808. CloseSpecDial()
  809. {
  810.     if (specDOpen)
  811.     {
  812.         CloseDialog(specDial);
  813.         specDOpen = FALSE;
  814.     }
  815. }
  816.  
  817. static
  818. DoWindwMenu(theItem)
  819. int theItem;
  820. {
  821.     switch    (theItem)
  822.     {
  823.     case WINDMEN_GRAPH: /* Show graph */
  824.         SelectWindow(graphWind);
  825.         break;
  826.     case WINDMEN_FUNCT: /* Show function */
  827.         ShowFunctDial();
  828.         break;
  829.     case WINDMEN_SPECS: /* Show Plot Specs*/
  830.         ShowSpecs();
  831.         break;
  832.     case WINDMEN_LIMITS: /* Show Limits */
  833.         ShowLimits();
  834.         break;
  835.     }
  836. }
  837.  
  838. static
  839. DoContent(whichWindow)
  840. WindowPtr whichWindow;
  841. {
  842.     if (whichWindow NEQ FrontWindow())
  843.         SelectWindow(whichWindow);
  844.     else if (FrontWindow() EQ graphWind)
  845.         ClikRot();
  846. }
  847.  
  848. Rect    hndRct[5], vertRect, horizRect, centrRect;
  849. Point    drawWCntr;
  850.  
  851. static
  852. ClikRot()
  853. {
  854.     Real    newRot[3][3], temp[3][3];
  855.     Real    rot;
  856.     Point    msDLoc;
  857.     int        quad;
  858.     int        WhatQuad();
  859.     int        XArcShow(), PYArcShow(), NZArcShow(), PZArcShow(), NYArcShow();
  860.  
  861.     msDLoc = theEvent.where;
  862.     GlobalToLocal(&msDLoc);
  863.     quad = WhatQuad(&msDLoc);
  864.     if (quad EQ -1)
  865.         return;
  866.  
  867.     switch (quad)
  868.     {
  869.     case 0:
  870.         rot = -DEGtoRAD * NYArcShow(&vertRect);
  871.         MkYRotMat(rot, newRot);
  872.         if (rot NEQ 0.0)
  873.             SRotatePoints(cos(rot), sin(rot), 2);
  874.         break;
  875.     case 3:
  876.         rot = -DEGtoRAD * NZArcShow(&horizRect);
  877.         MkZRotMat(rot, newRot);
  878.         if (rot NEQ 0.0)
  879.             SRotatePoints(cos(rot), sin(rot), 3);
  880.         break;
  881.     case 1:
  882.         rot = DEGtoRAD * PYArcShow(&vertRect);
  883.         MkYRotMat(rot, newRot);
  884.         if (rot NEQ 0.0)
  885.             SRotatePoints(cos(rot), sin(rot), 2);
  886.         break;
  887.     case 2:
  888.         rot = DEGtoRAD * PZArcShow(&horizRect);
  889.         MkZRotMat(rot, newRot);
  890.         if (rot NEQ 0.0)
  891.             SRotatePoints(cos(rot), sin(rot), 3);
  892.         break;
  893.     case 4:
  894.         rot = DEGtoRAD * XArcShow(¢rRect);
  895.         MkXRotMat(rot, newRot);
  896.         if (rot NEQ 0.0)
  897.             SRotatePoints(cos(rot), sin(rot), 4);
  898.         break;
  899.     }
  900.     pntsCurrent = FALSE;
  901.  
  902.     MatrxByMatrx(newRot, rotMatrx, temp);
  903.     CopyMat(temp, rotMatrx);
  904.  
  905.     InvalidGraph();
  906. }
  907.  
  908. static
  909. DoDrag(whichWindow)
  910. WindowPtr whichWindow;
  911. {
  912.     Rect limitRect;
  913.  
  914.     SetRect(&limitRect, 0, 0, 2000, 2000);
  915.     DragWindow(whichWindow, theEvent.where, &limitRect);
  916. }
  917.  
  918. DoGrow(whichWindow)
  919. WindowPtr whichWindow;
  920. {
  921.     Rect limitRect;
  922.     long    newSize;
  923.  
  924.     if (whichWindow EQ graphWind)
  925.     {
  926.         SetRect(&limitRect, 50, 50, 2000, 2000);
  927.         newSize = GrowWindow(whichWindow, theEvent.where, &limitRect);
  928.         if (newSize)
  929.         {
  930.             SizeWindow(whichWindow, LoWord(newSize), HiWord(newSize), TRUE);
  931.             if (whichWindow EQ graphWind)
  932.             {
  933.                 SetGraphRect();
  934.                 vectrsCurrent = FALSE;
  935.                 InvalidGraph();
  936.             }
  937.         }
  938.     }
  939. }
  940.  
  941. SetGraphRect()
  942. {
  943.     graphRect = graphWind->portRect;
  944.     InsetRect(&graphRect, 2, 2);
  945.     SetRotateHandles();
  946. }
  947.  
  948. static
  949. DoGoAway(whichWindow, needTrack)
  950. WindowPtr    whichWindow;
  951. Boolean        needTrack;
  952. {
  953.     if (needTrack)
  954.         if (NOT(TrackGoAway(whichWindow, theEvent.where)))
  955.             return;
  956.     if (whichWindow EQ graphWind)
  957.         exit();
  958.     else if (whichWindow EQ functDial)
  959.         CloseFunctDial();
  960.     else if (whichWindow EQ specDial)
  961.         CloseSpecDial();
  962.     else if (whichWindow EQ limtDial)
  963.     {
  964.         GetLimtDCont();
  965.         CloseDialog(limtDial);
  966.         limtDOpen = FALSE;
  967.     }
  968. }
  969.  
  970. static
  971. CloseFunctDial()
  972. {
  973.     if (functDOpen)
  974.     {
  975.         CloseDialog(functDial);
  976.         functDOpen = FALSE;
  977.     }
  978. }
  979.  
  980. GetSpecDCont()
  981. {
  982.     Real    temp;
  983.     Real    DialogField();
  984.  
  985.     if (NOT(specDOpen))
  986.         return;
  987.  
  988.     temp = DialogField(specDial, DIALI_S_SX);
  989.     specsCurrent = startX EQ temp;
  990.     startX = temp;
  991.  
  992.     temp = DialogField(specDial, DIALI_S_EX);
  993.     specsCurrent = specsCurrent AND (endX EQ temp);
  994.     endX = temp;
  995.  
  996.     temp = DialogField(specDial, DIALI_S_SY);
  997.     specsCurrent = specsCurrent AND (startY EQ temp);
  998.     startY = temp;
  999.  
  1000.     temp = DialogField(specDial, DIALI_S_EY);
  1001.     specsCurrent = specsCurrent AND (endY EQ temp);
  1002.     endY = temp;
  1003.  
  1004.     temp = (int)DialogField(specDial, 14);
  1005.     if ((numX-1) NEQ temp)
  1006.     {
  1007.         specsCurrent = FALSE;
  1008.         numX = temp;
  1009.         ++numX;
  1010.     }
  1011.  
  1012.     temp = (int)DialogField(specDial, 15);
  1013.     if ((numY-1) NEQ temp)
  1014.     {
  1015.         specsCurrent = FALSE;
  1016.         numY = temp;
  1017.         ++numY;
  1018.     }
  1019.     if (graphType EQ CYLIND_GTYPE)
  1020.     {
  1021.         startR = startX;
  1022.         endR = endX;
  1023.         numR = numX;
  1024.         startT = startY * DEGtoRAD;
  1025.         endT = endY * DEGtoRAD;
  1026.         numT = numY;
  1027.     }
  1028. }
  1029.  
  1030. static
  1031. Real
  1032. DialogField(theDialog, theItem)
  1033. DialogPtr    theDialog;
  1034. int    theItem;
  1035. {
  1036.     int        itemType;
  1037.     Handle    itemHndle;
  1038.     Rect    itemRect;
  1039.     char    contStr[256];
  1040.     Real    atof(), res;
  1041.  
  1042.     GetDItem(theDialog, theItem, &itemType, &itemHndle, &itemRect);
  1043.     GetIText(itemHndle, contStr);
  1044.  
  1045.     ptoc(contStr);
  1046.     res = atof(contStr);
  1047.     return(res);
  1048. }
  1049.  
  1050. GetLimtDCont()
  1051. {
  1052.     Real    temp;
  1053.     Real    DialogField();
  1054.  
  1055.     if (NOT(limtDOpen))
  1056.         return;
  1057.  
  1058.     temp = DialogField(limtDial, DIALI_L_ZS);
  1059.     vectrsCurrent = zScale EQ temp;
  1060.     zScale = temp;
  1061.  
  1062.     temp = DialogField(limtDial, DIALI_L_C);
  1063.     vectrsCurrent = vectrsCurrent AND (ceilgZ EQ temp);
  1064.     ceilgZ = temp;
  1065.  
  1066.     temp = DialogField(limtDial, DIALI_L_F);
  1067.     vectrsCurrent = vectrsCurrent AND (floorZ EQ temp);
  1068.     floorZ = temp;
  1069. }
  1070.  
  1071. /***  zoom box clicked  ***/
  1072. static
  1073. DoZoom(whichWindow, thePart)
  1074. WindowPtr    whichWindow;
  1075. int            thePart;
  1076. {
  1077.     if (TrackBox(whichWindow, theEvent.where, thePart))    /* ROM */
  1078.     {
  1079.         ZoomWindow(whichWindow, thePart, TRUE);    /* ROM */
  1080.         if (whichWindow EQ graphWind)
  1081.         {
  1082.             SetGraphRect();
  1083.             vectrsCurrent = FALSE;
  1084.         }
  1085.     }
  1086. }
  1087.  
  1088. static
  1089. DoKeyDown()
  1090. {
  1091.     unsigned    char typed;
  1092.     long menuChoice;
  1093.  
  1094.     typed = theEvent.message & charCodeMask;
  1095.  
  1096.     if ((theEvent.modifiers & cmdKey)
  1097.         AND (theEvent.what NEQ autoKey)) /* ignore repeats */
  1098.     {
  1099.         menuChoice = MenuKey(typed);
  1100.         if (menuChoice)
  1101.             DoMenuChoice(menuChoice);
  1102.     }
  1103. }
  1104.  
  1105. static
  1106. DoUpdate()
  1107. {
  1108.     GrafPtr savePort;        /* to save and restore the old port */
  1109.     WindowPtr whichWindow;
  1110.  
  1111.     Clock();
  1112.     whichWindow = (WindowPtr) (theEvent.message);
  1113.  
  1114.     BeginUpdate(whichWindow);    /* reset ClipRgn etc to only redraw what's
  1115.                                necessary. */
  1116.  
  1117.         GetPort(&savePort);        /* don't trash the port; we might be
  1118.                                    updating an inactive window */
  1119.         SetPort(whichWindow);    /* work in the specified window */
  1120.  
  1121.         DrawWindow(whichWindow);
  1122.  
  1123.     EndUpdate(whichWindow);
  1124.  
  1125.     SetPort(savePort);
  1126. }
  1127.  
  1128. static
  1129. DrawWindow(whichWindow)
  1130. WindowPtr whichWindow;
  1131. {
  1132.     if (whichWindow EQ graphWind)
  1133.         UpdatGraphWind();
  1134. }
  1135.  
  1136. static
  1137. UpdatGraphWind()
  1138. {
  1139.     ClipRect(&graphWind->portRect);
  1140.  
  1141.     if (noRedrawGrph)
  1142.         return;
  1143.  
  1144.     if (NOT(vectrsCurrent))
  1145.     {
  1146.         if (graphType EQ CYLIND_GTYPE)
  1147.             SetCylindVectrs();
  1148.         else
  1149.             SetVectrs();
  1150.         pntsCurrent = FALSE;
  1151.     }
  1152.     if (hideSurface)
  1153.         if (scrnColor NEQ colorNorms)
  1154.             pntsCurrent = FALSE;
  1155.     if (NOT(pntsCurrent))
  1156.         SetPoints();
  1157.  
  1158.     CheckGrphWind();
  1159.     DrawGraph();
  1160.     PutGraphGrow();
  1161.     if (startRedraw NEQ -1)
  1162.         if ((Ticks - startRedraw) > 1800)
  1163.             SysBeep(1);
  1164.     startRedraw  = -1;
  1165.     DrawRotHndls();
  1166. }
  1167.  
  1168. PutGraphGrow()
  1169. {
  1170.     Rect    theRect;
  1171.  
  1172.     theRect = graphWind->portRect;
  1173.     theRect.left = theRect.right - SCBAR_WIDTH;
  1174.     theRect.top = theRect.bottom - SCBAR_WIDTH;
  1175.     ClipRect(&theRect);
  1176.     DrawGrowIcon(graphWind);
  1177.     ClipRect(&graphWind->portRect);
  1178. }
  1179.  
  1180. DrawGraph()
  1181. {
  1182. register    int    xCnt, yCnt;
  1183. register    Point    *grphPnts;
  1184.     Boolean        CmndPeriod();
  1185.  
  1186.     if (hideSurface)
  1187.     {
  1188.         DrawHiddenGraph();
  1189.         return;
  1190.     }
  1191.  
  1192.     EraseRect(&thePort->portRect);
  1193.     DrawAxes();
  1194.     if (drawToScreen AND (FrontWindow() EQ graphWind) AND NOT(scrnColor) AND grphOnScrn AND appActive)
  1195.     {
  1196.         HideCursor();
  1197.         grphPnts = graphPoints;
  1198.         xCnt = numX;
  1199.         while (xCnt--)
  1200.         {
  1201. //            if (CmndPeriod())
  1202. //            {
  1203. //                ShowCursor();
  1204. //                return;
  1205. //            }
  1206.             MoveTo(*grphPnts++);
  1207.             yCnt = numY;
  1208.             while (--yCnt)
  1209.                 MLineTo(*grphPnts++);
  1210.         }
  1211.  
  1212.         for (yCnt = 0; yCnt < numY; yCnt++)
  1213.         {
  1214.             MoveTo(graphPoints[yCnt]);
  1215. //            if (CmndPeriod())
  1216. //            {
  1217. //                ShowCursor();
  1218. //                return;
  1219. //            }
  1220.             grphPnts = graphPoints + (numY + yCnt);
  1221.             for (xCnt = 1; xCnt < numX; xCnt++)
  1222.             {
  1223.                 MLineTo(*grphPnts);
  1224.                 grphPnts += numY;
  1225.             }
  1226.         }
  1227.         ShowCursor();
  1228.     }
  1229.     else
  1230.     {
  1231.         grphPnts = graphPoints;
  1232.         xCnt = numX;
  1233.         while (xCnt--)
  1234.         {
  1235.             if (CmndPeriod())
  1236.                 return;
  1237.             MoveTo(*grphPnts++);
  1238.             yCnt = numY;
  1239.             while (--yCnt)
  1240.                 LineTo(*grphPnts++);
  1241.         }
  1242.         
  1243.         for (yCnt = 0; yCnt < numY; yCnt++)
  1244.         {
  1245.             MoveTo(graphPoints[yCnt]);
  1246.             if (CmndPeriod())
  1247.                 return;
  1248.             grphPnts = graphPoints + (numY + yCnt);
  1249.             for (xCnt = 1; xCnt < numX; xCnt++)
  1250.             {
  1251.                 LineTo(*grphPnts);
  1252.                 grphPnts += numY;
  1253.             }
  1254.         }
  1255.     }
  1256. }
  1257.  
  1258. static
  1259. DrawAxes()
  1260. {
  1261.     PenSize(2, 2);
  1262.     MoveTo(pass(Origin));
  1263.     LineTo(pass(XaxisPt));
  1264.     MoveTo(pass(Origin));
  1265.     LineTo(pass(YaxisPt));
  1266.     MoveTo(pass(Origin));
  1267.     LineTo(pass(ZaxisPt));
  1268.     PenSize(1, 1);
  1269. }
  1270.  
  1271. static
  1272. DrawHiddenGraph()
  1273. {
  1274.     PolyHandle    thePoly;
  1275.  
  1276.     if (xAxPos) {
  1277.         if (yAxPos)
  1278.             HideIt(0, 0, 1, 1, numX-1, numY-1);
  1279.         else
  1280.             HideIt(0, numY-2, 1, -1, numX-1, -1);
  1281.     }
  1282.     else {
  1283.         if (yAxPos)
  1284.             HideIt(numX-2, 0, -1, 1, -1, numY-1);
  1285.         else
  1286.             HideIt(numX-2, numY-2, -1, -1, -1, -1);
  1287.     }
  1288. }
  1289.  
  1290. static
  1291. HideIt(xStrt, yStrt, xStep, yStep, xEnd, yEnd)
  1292. int            xStrt, yStrt;
  1293. register    int    xStep, yStep;
  1294. int            xEnd, yEnd;
  1295. {
  1296. register    int    xCnt, yCnt;
  1297. register    long    offSet;
  1298.     PolyHandle     thePoly;
  1299.     Boolean        CmndPeriod();
  1300.  
  1301.     EraseRect(&thePort->portRect);
  1302.  
  1303.     for (xCnt = xStrt; xCnt NEQ xEnd; xCnt += xStep)
  1304.     {
  1305.         for (yCnt = yStrt; yCnt NEQ yEnd; yCnt += yStep)
  1306.         {
  1307.             thePoly = OpenPoly();
  1308.             offSet = (long)xCnt * numY + (long)yCnt;
  1309.             MoveTo(graphPoints[offSet]);
  1310.             LineTo(graphPoints[(long)xCnt * numY + (long)(yCnt+1)]);
  1311.             LineTo(graphPoints[(long)(xCnt+1) * numY + (long)(yCnt+1)]);
  1312.             LineTo(graphPoints[(long)(xCnt+1) * numY + (long)yCnt]);
  1313.             LineTo(graphPoints[offSet]);
  1314.             ClosePoly();
  1315.             SetGray(gridFace[offSet]);
  1316.             PaintPoly(thePoly);
  1317.             KillPoly(thePoly);
  1318.         }
  1319.         if (CmndPeriod())
  1320.             break;  /* for */
  1321.     }
  1322.     SetBlack();
  1323. }
  1324.  
  1325. static
  1326. SetBlack()
  1327. {
  1328.     RGBColor    theColor;
  1329.  
  1330.     if (scrnColor)
  1331.     {
  1332.         theColor.red = theColor.blue = theColor.green = 0;
  1333.         RGBForeColor(&theColor);
  1334.     }
  1335.     else
  1336.         PenPat(black);
  1337. }
  1338.  
  1339. static
  1340. FitRect(theRect, thePoint)
  1341. register    Rect    *theRect;
  1342. register    Point    *thePoint;
  1343. {
  1344.     if (thePoint->h < theRect->left)
  1345.         theRect->left = thePoint->h;
  1346.     else if (thePoint->h > theRect->right)
  1347.         theRect->right = thePoint->h;
  1348.  
  1349.     if (thePoint->v < theRect->top)
  1350.         theRect->top = thePoint->v;
  1351.     else if (thePoint->v > theRect->bottom)
  1352.         theRect->bottom = thePoint->v;
  1353. }
  1354.  
  1355.  
  1356. static
  1357. DoActivate()
  1358. {
  1359.     WindowPtr whichWindow;
  1360.  
  1361.     whichWindow = (WindowPtr) (theEvent.message);
  1362.     if (theEvent.modifiers & activeFlag)
  1363.     {
  1364.         ReadDeskScrap();
  1365.         SetPort(whichWindow);
  1366.     }
  1367.     else
  1368.         WriteDeskScrap();
  1369.  
  1370.     if (whichWindow EQ graphWind)
  1371.         PutGraphGrow();
  1372. }
  1373.  
  1374. static
  1375. DoSuspndRsm(message)
  1376. long    message;
  1377. {
  1378.     if (HIBYTE(message) NEQ 1)
  1379.         return;    /* not a suspend/resume */
  1380.  
  1381.     if (IS_SUSPND(message))
  1382.     {
  1383.         if (LOAD_CLIP(message))
  1384.             WriteDeskScrap();
  1385.         appActive = FALSE;
  1386.     }
  1387.     else    /* resume event */
  1388.     {
  1389.         if (LOAD_CLIP(message))    /* read back the clipboard? */
  1390.             ReadDeskScrap();
  1391.         appActive = TRUE;
  1392.     }
  1393. }
  1394.  
  1395. ShowFunctDial()
  1396. {
  1397.     if (functDOpen)
  1398.         SelectWindow(functDial);
  1399.     else
  1400.     {
  1401.         if (graphType EQ FUNCT_GTYPE)
  1402.             functDial = GetNewDialog(DIAL_FUNCT, &funcDialRecord, (DialogPtr)-1L);
  1403.         else if (graphType EQ CYLIND_GTYPE)
  1404.             functDial = GetNewDialog(DIAL_CYLIND, &funcDialRecord, (DialogPtr)-1L);
  1405.         else if (graphType EQ DERIV_GTYPE)
  1406.             functDial = GetNewDialog(DIAL_DERIV, &funcDialRecord, (DialogPtr)-1L);
  1407.         functDOpen = TRUE;
  1408.     }
  1409. }
  1410.  
  1411. ShowSpecs()
  1412. {
  1413.     if (specDOpen)
  1414.         SelectWindow(specDial);
  1415.     else {
  1416.         switch    (graphType) {
  1417.         case FUNCT_GTYPE:
  1418.             specDial = GetNewDialog(DIAL_SCALE_XY, &sdialRecord, (DialogPtr)-1L);
  1419.             specDOpen = TRUE;
  1420.             break;
  1421.         case CYLIND_GTYPE:
  1422.             specDial = GetNewDialog(DIAL_SCALE_RP, &sdialRecord, (DialogPtr)-1L);
  1423.             specDOpen = TRUE;
  1424.             break;
  1425.         case DERIV_GTYPE:
  1426.             specDial = GetNewDialog(DIAL_SCALE_XY, &sdialRecord, (DialogPtr)-1L);
  1427.             specDOpen = TRUE;
  1428.             break;
  1429.         case FDATA_GTYPE:
  1430.             break;
  1431.         }
  1432.     }
  1433. }
  1434.  
  1435. ShowLimits()
  1436. {
  1437.     if (limtDOpen)
  1438.         SelectWindow(limtDial);
  1439.     else {
  1440.         limtDial = GetNewDialog(DIAL_LIMT, &lmdialRecord, (DialogPtr)-1L);
  1441.         limtDOpen = TRUE;
  1442.     }
  1443. }
  1444.  
  1445. static
  1446. int
  1447. PZArcShow(theRect)
  1448. Rect    *theRect;
  1449. {
  1450.     Point    currMouseLoc;
  1451.     int        degrs, oldDegrs;
  1452.  
  1453.     GetMouse(&currMouseLoc);
  1454.     degrs = (180.0 / (Real)(theRect->right - theRect->left))
  1455.             * currMouseLoc.h;
  1456.     oldDegrs = degrs;
  1457.     InvertArc(theRect, 270 - degrs, degrs);
  1458.  
  1459.     while (Button())
  1460.     {
  1461.         GetMouse(&currMouseLoc);
  1462.         degrs = (180.0 / (Real)(theRect->right - theRect->left))
  1463.                 * currMouseLoc.h;
  1464.         if (degrs < 0)
  1465.             degrs = 0;
  1466.         else if (degrs > 180)
  1467.             degrs = 180;
  1468.         if (degrs NEQ oldDegrs)
  1469.         {
  1470.             InvertArc(theRect, 270 - degrs, degrs - oldDegrs);
  1471.             oldDegrs = degrs;
  1472.         }
  1473.     }
  1474.     InvertArc(theRect, 270 - degrs, degrs);
  1475.     return(degrs);
  1476. }
  1477.  
  1478. static
  1479. int
  1480. NZArcShow(theRect)
  1481. Rect    *theRect;
  1482. {
  1483.     Point    currMouseLoc;
  1484.     int        degrs, oldDegrs, widthRect;
  1485.  
  1486.     widthRect = theRect->right - theRect->left;
  1487.     GetMouse(&currMouseLoc);
  1488.     degrs = (180.0 / (Real)(widthRect))
  1489.             * (widthRect - currMouseLoc.h);
  1490.     oldDegrs = degrs;
  1491.     InvertArc(theRect, 90, degrs);
  1492.  
  1493.     while (Button())
  1494.     {
  1495.         GetMouse(&currMouseLoc);
  1496.         degrs = (180.0 / (Real)(widthRect))
  1497.                 * (widthRect - currMouseLoc.h);
  1498.         if (degrs < 0)
  1499.             degrs = 0;
  1500.         else if (degrs > 180)
  1501.             degrs = 180;
  1502.         if (degrs NEQ oldDegrs)
  1503.         {
  1504.             if (degrs < oldDegrs)
  1505.                 InvertArc(theRect, degrs + 90, oldDegrs - degrs);
  1506.             else
  1507.                 InvertArc(theRect, oldDegrs + 90, degrs - oldDegrs);
  1508.             oldDegrs = degrs;
  1509.         }
  1510.     }
  1511.  
  1512.     InvertArc(theRect, 90, degrs);
  1513.     return(degrs);
  1514. }
  1515.  
  1516.  
  1517. static
  1518. int
  1519. NYArcShow(theRect)
  1520. Rect    *theRect;
  1521. {
  1522.     Point    currMouseLoc;
  1523.     int        degrs, oldDegrs, heightRect;
  1524.  
  1525.     heightRect = theRect->bottom - theRect->top;
  1526.     GetMouse(&currMouseLoc);
  1527.     degrs = (180.0 / (Real)(heightRect))
  1528.             * currMouseLoc.v;
  1529.     oldDegrs = degrs;
  1530.     InvertArc(theRect, 0, degrs);
  1531.  
  1532.     while (Button())
  1533.     {
  1534.         GetMouse(&currMouseLoc);
  1535.         degrs = (180.0 / (Real)(heightRect))
  1536.                 * currMouseLoc.v;
  1537.         if (degrs < 0)
  1538.             degrs = 0;
  1539.         else if (degrs > 180)
  1540.             degrs = 180;
  1541.         if (degrs NEQ oldDegrs)
  1542.         {
  1543.             if (degrs < oldDegrs)
  1544.                 InvertArc(theRect, degrs, oldDegrs - degrs);
  1545.             else
  1546.                 InvertArc(theRect, oldDegrs, degrs - oldDegrs);
  1547.             oldDegrs = degrs;
  1548.         }
  1549.     }
  1550.     InvertArc(theRect, 0, degrs);
  1551.  
  1552.     return(degrs);
  1553. }
  1554.  
  1555. static
  1556. int
  1557. PYArcShow(theRect)
  1558. Rect    *theRect;
  1559. {
  1560.     Point    currMouseLoc;
  1561.     int        degrs, oldDegrs, heightRect;
  1562.  
  1563.     heightRect = theRect->bottom - theRect->top;
  1564.     GetMouse(&currMouseLoc);
  1565.     degrs = (180.0 / (Real)(heightRect))
  1566.             * (heightRect - currMouseLoc.v);
  1567.     oldDegrs = degrs;
  1568.     InvertArc(theRect, 180 - degrs, degrs);
  1569.  
  1570.     while (Button())
  1571.     {
  1572.         GetMouse(&currMouseLoc);
  1573.         degrs = (180.0 / (Real)(heightRect))
  1574.                 * (heightRect - currMouseLoc.v);
  1575.         if (degrs < 0)
  1576.             degrs = 0;
  1577.         else if (degrs > 180)
  1578.             degrs = 180;
  1579.         if (degrs NEQ oldDegrs)
  1580.         {
  1581.             if (degrs < oldDegrs)
  1582.                 InvertArc(theRect, 180 - oldDegrs, oldDegrs - degrs);
  1583.             else
  1584.                 InvertArc(theRect, 180 - degrs, degrs - oldDegrs);
  1585.             oldDegrs = degrs;
  1586.         }
  1587.     }
  1588.     InvertArc(theRect, 180 - degrs, degrs);
  1589.  
  1590.     return(degrs);
  1591. }
  1592.  
  1593. static
  1594. int
  1595. XArcShow(theRect)
  1596. Rect    *theRect;
  1597. {
  1598.     int        degrs, oldDegrs;
  1599.     double    angle, MouseAngle();
  1600.     Point    currMsPos, oldMsPos, presPos, oldPos;
  1601.     int        startAngle, oldAngle, presAngle, rotAngle;
  1602.  
  1603.     PenMode(patXor);
  1604.     PenSize(2, 2);
  1605.     GetMouse(&oldMsPos);
  1606.     oldPos = drawWCntr;
  1607.  
  1608.     do
  1609.     {
  1610.         GetMouse(&currMsPos);
  1611.         if ((currMsPos.h NEQ oldMsPos.h) OR (currMsPos.v NEQ oldMsPos.v))
  1612.         {
  1613.             angle = MouseAngle(currMsPos);
  1614.             presPos.h = (int)(drawWCntr.v * sin(angle)) + drawWCntr.h;
  1615.             presPos.v = -(int)(drawWCntr.v * cos(angle)) + drawWCntr.v;
  1616.             angle = MouseAngle(currMsPos);
  1617.             presPos.h = (int)(drawWCntr.v * sin(angle)) + drawWCntr.h;
  1618.             presPos.v = -(int)(drawWCntr.v * cos(angle)) + drawWCntr.v;
  1619.             ReDrwLine(drawWCntr.v, drawWCntr.h, presPos, oldPos);
  1620.             oldPos = presPos;
  1621.             oldMsPos = currMsPos;
  1622.         }
  1623.     } while (Button());
  1624.     startAngle = round(angle * RADtoDEG);
  1625.  
  1626.     oldAngle = startAngle;
  1627.     do
  1628.     {
  1629.         GetMouse(&currMsPos);
  1630.         if ((currMsPos.h NEQ oldMsPos.h) OR (currMsPos.v NEQ oldMsPos.v))
  1631.         {
  1632.             angle = MouseAngle(currMsPos) * RADtoDEG;
  1633.             presAngle = round(angle);
  1634.             rotAngle = RelativAngle(startAngle, presAngle);
  1635.  
  1636.             InvertArc(theRect, startAngle + RelativAngle(startAngle, oldAngle),
  1637.                     RelativAngle(startAngle, presAngle)
  1638.                     - RelativAngle(startAngle, oldAngle));
  1639.  
  1640.             oldAngle = presAngle;
  1641.             oldMsPos = currMsPos;
  1642.         }
  1643.     } while (NOT(Button()));
  1644.  
  1645.     if (presAngle - startAngle > 0)
  1646.         return(presAngle - startAngle);
  1647.     else
  1648.         return(360 + presAngle - startAngle);
  1649.     PenMode(patCopy);
  1650.     PenSize(1, 1);
  1651. }
  1652.  
  1653. /*** Update the position of a line ***/
  1654. void
  1655. ReDrwLine(strt, presPos, oldPos)
  1656. Point        strt, presPos, oldPos;
  1657. {
  1658.     MoveTo(strt);
  1659.     LineTo(oldPos);
  1660.     MoveTo(strt);
  1661.     LineTo(presPos);
  1662. }
  1663.  
  1664.  
  1665. double
  1666. MouseAngle(currMsLoc)
  1667. Point    currMsLoc;
  1668. {
  1669.     Point    msCntrLoc;
  1670.     double    angle;
  1671.  
  1672.     msCntrLoc.h = currMsLoc.h - drawWCntr.h;
  1673.     msCntrLoc.v = currMsLoc.v - drawWCntr.v;
  1674.     angle = atan((double)msCntrLoc.h / msCntrLoc.v);
  1675.     angle = Abs(angle);
  1676.  
  1677.     if (msCntrLoc.h > 0)
  1678.         if (msCntrLoc.v > 0)
  1679.             angle = PI - angle;
  1680.         else
  1681.         {}
  1682.     else
  1683.     {
  1684.         if (msCntrLoc.v > 0)
  1685.             angle -= PI;
  1686.         else
  1687.             angle = -angle;
  1688.     }
  1689.  
  1690.     return(angle);
  1691. }
  1692.  
  1693.  
  1694. int
  1695. RelativAngle(startAngle, presAngle)
  1696. int    startAngle, presAngle;
  1697. {
  1698.     int    relAngle;
  1699.  
  1700.     if (presAngle - startAngle > 0)
  1701.         relAngle = (presAngle - startAngle);
  1702.     else
  1703.         relAngle = (360 + presAngle - startAngle);
  1704.     if (relAngle > 180)
  1705.         relAngle -= 360;
  1706.     return(relAngle);
  1707. }
  1708.  
  1709. My_printf(shwStr)
  1710. char    *shwStr;
  1711. {
  1712.     char    pbuffer[256];
  1713.     GrafPtr    savePort;
  1714. static    Rect    dispRect = {21, 320, 40, 510};
  1715.     
  1716.     GetPort(&savePort);
  1717.     SetPort(windManPort);
  1718.         ClipRect(&dispRect);
  1719.         EraseRect(&dispRect);
  1720.         MoveTo(330, 36);
  1721.         strcpy(pbuffer, shwStr);
  1722.         ctop(pbuffer);
  1723.         DrawString(pbuffer);
  1724.     SetPort(savePort);
  1725. }
  1726.  
  1727. Wait()
  1728. {
  1729.     EventRecord    msEvent;
  1730.     
  1731.     while(!Button());
  1732.     while(Button());
  1733.     GetNextEvent(mDownMask, &msEvent);
  1734. }
  1735.  
  1736. static    GrafPtr    _oldPort;
  1737.  
  1738. SavePort()
  1739. {
  1740.     GetPort(&_oldPort);
  1741. }
  1742.  
  1743. RestorePort()
  1744. {
  1745.     SetPort(_oldPort);
  1746. }
  1747.  
  1748.  
  1749. static    DialogPtr        meterDlg;
  1750. static    Real    meterAngle, lstDrwnAngle, meterDelta;
  1751. static    Rect    meterRect = { 10, 10, 93, 93 };
  1752.  
  1753. ShowMeter(elements)
  1754. long    elements;
  1755. {
  1756. static    DialogRecord    meterRecord;    /* storage for the dialog */
  1757.  
  1758.     if (inMultiFndr)
  1759.     {
  1760.         SavePort();
  1761.         SelectWindow(graphWind);
  1762.         SetPort(graphWind);
  1763.         EraseRect(&meterRect);
  1764.         FrameOval(&meterRect);
  1765.         RestorePort();
  1766.     }
  1767.     else
  1768.     {
  1769.         meterDlg = GetNewDialog(DIAL_METER, &meterRecord, (DialogPtr)-1L);
  1770.         DrawDialog(meterDlg);
  1771.         SavePort();
  1772.         SetPort(meterDlg);
  1773.         FrameOval(&meterRect);
  1774.     }
  1775.  
  1776.     meterDelta = 360.0 / elements;
  1777.     meterAngle = lstDrwnAngle = 0.0;
  1778. }
  1779.  
  1780. DisplayMeter()
  1781. {
  1782.     GrafPtr    svPort;
  1783.  
  1784.     meterAngle += meterDelta;
  1785.     if (meterAngle > (lstDrwnAngle + 3))
  1786.     {
  1787.         lstDrwnAngle = meterAngle;
  1788.         if (inMultiFndr)
  1789.         {
  1790.             GetPort(&svPort);
  1791.             SetPort(graphWind);
  1792.             FillArc(&meterRect, 0, (int)meterAngle, black);
  1793.             SetPort(svPort);
  1794.         }
  1795.         else
  1796.             FillArc(&meterRect, 0, (int)meterAngle, black);
  1797.     }
  1798. }
  1799.  
  1800. RemoveMeter()
  1801. {
  1802.     register    int    i = 4;
  1803.  
  1804.     if (NOT(inMultiFndr))
  1805.     {
  1806.         CloseDialog(meterDlg);
  1807.     
  1808.         noRedrawGrph = TRUE;
  1809.         RestorePort();
  1810.         while (i--)
  1811.             if (GetNextEvent(updateMask, &theEvent))
  1812.                 DoEvent();
  1813.         noRedrawGrph = FALSE;
  1814.     }
  1815. }
  1816.  
  1817.  
  1818.  
  1819. /***  read in deskscrap (clipboard)  ***/
  1820. ReadDeskScrap()
  1821. {
  1822.     long    scrapLen, scrapOffset;
  1823.  
  1824.     if (scrapCompare NEQ ScrapInfo.scrapCount)
  1825.     {
  1826.         scrapLen = GetScrap(NIL, 'TEXT', &scrapOffset);
  1827.         if (scrapLen >= 0)
  1828.             if (TEFromScrap() < 0)    /* ROM */
  1829.                 scrapLen = 0;    /* was an error */
  1830.         if (NOT(scrapLen))
  1831.         {
  1832.             TESetScrapLen(0);    /* ROM */
  1833.             isScrapTE = FALSE;
  1834.         }
  1835.         else
  1836.             isScrapTE = TRUE;
  1837.  
  1838.         scrapCompare = ScrapInfo.scrapCount;
  1839.     }
  1840.     SetEditMenu();
  1841. }
  1842.  
  1843. /***  write out deskscrap (clipboard)  ***/
  1844. WriteDeskScrap()
  1845. {
  1846.     if (scrapDirty AND isScrapTE)
  1847.     {
  1848.         scrapCompare = ZeroScrap();
  1849.         TEToScrap();    /* ROM */
  1850.         scrapDirty = FALSE;
  1851.     }
  1852.     SetEditMenu();
  1853. }
  1854.  
  1855. SetPlotMenu()
  1856. {
  1857.     if (hideSurface)
  1858.         DisableItem(plotMenu, PLOT_DRWSCRN);
  1859.     else
  1860.         EnableItem(plotMenu, PLOT_DRWSCRN);
  1861. }
  1862.  
  1863. /***  enable or gray out approriate items in the menu  ***/
  1864. SetEditMenu()
  1865. {
  1866.     WindowPtr frontW;
  1867.     Boolean        IsDialog(), IsList();
  1868.  
  1869.     frontW = FrontWindow();
  1870.     if (frontW EQ graphWind)
  1871.     {
  1872.         DisableItem(editMenu, EDIT_UNDO);    /* ROM */
  1873.         DisableItem(editMenu, EDIT_CUT);
  1874.         EnableItem(editMenu, EDIT_COPY);
  1875.         DisableItem(editMenu, EDIT_PASTE);
  1876.         DisableItem(editMenu, EDIT_CLEAR);
  1877.     }
  1878.     else if (IsDialog(frontW))
  1879.     {
  1880.         DisableItem(editMenu, EDIT_UNDO);    /* ROM */
  1881.         EnableItem(editMenu, EDIT_CUT);
  1882.         EnableItem(editMenu, EDIT_COPY);
  1883.         if (isScrapTE)
  1884.             EnableItem(editMenu, EDIT_PASTE);
  1885.         else
  1886.             DisableItem(editMenu, EDIT_PASTE);
  1887.         EnableItem(editMenu, EDIT_CLEAR);
  1888.     }
  1889.     else    /* menu for DA */
  1890.     {
  1891.         EnableItem(editMenu, EDIT_UNDO);
  1892.         EnableItem(editMenu, EDIT_CUT);
  1893.         EnableItem(editMenu, EDIT_COPY);
  1894.         EnableItem(editMenu, EDIT_PASTE);
  1895.         EnableItem(editMenu, EDIT_CLEAR);
  1896.     }
  1897. }
  1898.  
  1899. #define    KEYMAP    ((long *)0x174)
  1900.  
  1901. int
  1902. ShiftDown()
  1903. {
  1904.     return(KEYMAP[1] & 1);
  1905. }
  1906.  
  1907. int
  1908. OptionDown()
  1909. {
  1910.     return(KEYMAP[1] & 4);
  1911. }
  1912.  
  1913. int
  1914. CapsDown()
  1915. {
  1916.     return(KEYMAP[1] & 2);
  1917. }
  1918.  
  1919.  
  1920. pascal void
  1921. RMoveTo(a)
  1922. long    a;
  1923. {
  1924.     asm{
  1925.         move.l  a,-(a7)
  1926.         move.l  MoveToAddr,a0
  1927.         jsr     (a0)
  1928.     }
  1929. }
  1930.  
  1931. pascal void
  1932. RLineTo(a)
  1933. long    a;
  1934. {
  1935.     asm{
  1936.         move.l  a,-(a7)
  1937.         move.l  LineToAddr,a0
  1938.         jsr     (a0)
  1939.     }
  1940. }
  1941.  
  1942. Clock()
  1943. {
  1944.     CursHandle        theCursH;
  1945.  
  1946.     theCursH = GetCursor(4);
  1947.     SetCursor(*theCursH);
  1948. }
  1949.  
  1950. GenralAlert(mesg)
  1951. char    *mesg;
  1952. {
  1953.     ParamText(mesg, "", "", "");
  1954.     InitCursor();
  1955.     Alert(ALERT_GENRAL, NIL);
  1956. }
  1957.  
  1958.  
  1959.  
  1960. /*********************************************/
  1961. /*****    MultiFinder "multitasking" stuff *****/
  1962.  
  1963.  
  1964. Boolean
  1965. CmndPeriod()
  1966. {
  1967.     int        evntMask;
  1968.     EventRecord    keyEvent;
  1969.     Boolean        CmndEvent();
  1970. static    long    lastTm = 0xf0000000;
  1971.  
  1972.     if (appActive)
  1973.         if ((Ticks - lastTm) < 15)
  1974.             return(FALSE);
  1975.     lastTm = Ticks;
  1976.  
  1977.     if (inMultiFndr)
  1978.     {
  1979.         evntMask = everyEvent - updateMask;
  1980.         if (WaitNextEvent(evntMask, &keyEvent, sleepPeriod, NIL))
  1981.         {
  1982.             if (keyEvent.what EQ resumEvt)
  1983.                 DoSuspndRsm(keyEvent.message);
  1984.             else if (CmndEvent(&keyEvent))
  1985.                 return(TRUE);
  1986.         }
  1987.     }
  1988.     else
  1989.     {
  1990.         SystemTask();
  1991.         if (EventAvail(keyDownMask, &keyEvent))
  1992.             if (CmndEvent(&keyEvent))
  1993.                 return(TRUE);
  1994.     }
  1995.     return(FALSE);    
  1996. }
  1997.  
  1998. static
  1999. Boolean
  2000. CmndEvent(chkEvent)
  2001. EventRecord        *chkEvent;
  2002. {
  2003.     if (chkEvent->what EQ keyDown)
  2004.         if ((chkEvent->message & charCodeMask) EQ '.')
  2005.             if (chkEvent->modifiers & cmdKey)
  2006.                 return(TRUE);
  2007.     return(FALSE);
  2008. }
  2009.  
  2010.  
  2011.  
  2012.  
  2013.  
  2014.  
  2015. SetRotateHandles()
  2016. {
  2017.     int        halfWid, width;
  2018.     Rect    drawRect;
  2019.  
  2020.     drawRect = graphWind->portRect;
  2021.     drawWCntr.h = DIV_2(drawRect.right - drawRect.left) + drawRect.left;
  2022.     drawWCntr.v = DIV_2(drawRect.bottom - drawRect.top) + drawRect.top;
  2023.  
  2024.     hndRct[0].top = drawRect.top - 1;
  2025.     hndRct[0].left = drawWCntr.h - 7;
  2026.     hndRct[0].bottom = hndRct[0].top + 13;
  2027.     hndRct[0].right = drawWCntr.h + 7;
  2028.  
  2029.     hndRct[1].top = drawRect.bottom - 12;
  2030.     hndRct[1].left = hndRct[0].left;
  2031.     hndRct[1].bottom = drawRect.bottom + 1;
  2032.     hndRct[1].right = hndRct[0].right;
  2033.  
  2034.     hndRct[2].top = drawWCntr.v - 7;
  2035.     hndRct[2].bottom = drawWCntr.v + 7;
  2036.     hndRct[2].left = -1;
  2037.     hndRct[2].right = 12;
  2038.  
  2039.     hndRct[3].top = hndRct[2].top;
  2040.     hndRct[3].left = drawRect.right - 12;
  2041.     hndRct[3].bottom = hndRct[2].bottom;
  2042.     hndRct[3].right = drawRect.right + 1;
  2043.  
  2044.     hndRct[4].top = drawRect.top - 1;
  2045.     hndRct[4].bottom = hndRct[4].top + 13;
  2046.     hndRct[4].left = -1;
  2047.     hndRct[4].right = 12;
  2048.  
  2049.     width = (MIN(drawWCntr.h, drawWCntr.v) * 100) / 152;
  2050.     halfWid = width / 2;
  2051.  
  2052.     vertRect.top = drawRect.top;
  2053.     vertRect.left = drawWCntr.h - halfWid;
  2054.     vertRect.bottom = drawRect.bottom;
  2055.     vertRect.right = drawWCntr.h + halfWid;
  2056.  
  2057.     horizRect.top = drawWCntr.v - halfWid;
  2058.     horizRect.left = 0;
  2059.     horizRect.bottom = drawWCntr.v + halfWid;
  2060.     horizRect.right = drawRect.right;
  2061.  
  2062.     centrRect.top = drawWCntr.v - width;
  2063.     centrRect.left = drawWCntr.h - width;
  2064.     centrRect.bottom = drawWCntr.v + width;
  2065.     centrRect.right = drawWCntr.h + width;
  2066. }
  2067.  
  2068. DrawRotHndls()
  2069. {
  2070.     int        i;
  2071.  
  2072.     PenMode(patXor);
  2073.     for (i = 0; i < 5; i++)
  2074.         FrameRect(hndRct + i);
  2075.     PenMode(patCopy);
  2076. }
  2077.  
  2078. int
  2079. WhatQuad(pntPtr)
  2080. Point    *pntPtr;
  2081. {
  2082.     int        i;
  2083.  
  2084.     for (i = 0; i < 5; i++)
  2085.         if (PtInRect(*pntPtr, hndRct + i))
  2086.             return(i);
  2087.     return(-1);
  2088. }
  2089.